package cn.hicard.auth.web;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.Charset;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
 * <p>获取response对象，并将输出存放在自定义的流里面，然后就可以自由控制向浏览器输出的内容了</p>
 * 1）以流的方式获取输出——重写getOutputStream()  [经验证如果不调用的话则没必要，核心是PrintWriter]<br/>
 * 2）以字符方式获取输出——重写getWriter() <br/>
 * 3）刷新流——重写flushBuffer() <br/>
 * 4）重置流——重写reset() <br/>
 * 5 ) 加入新增的获取输出数据的方法<br/>
 * @author zhangy
 */
public class AuthServletResponseWrapper extends HttpServletResponseWrapper {

	// 内存输出数据流
	private ByteArrayOutputStream output;
	// 输出
	private PrintWriter writer;
	// 字符编码
	private String charEncoding;
	// Http状态
	private int httpStatus;
	
	/**
	 * 根据原始HttpServletResponse和指的编码构造一个AuthServletResponseWrapper
	 * @param response
	 * @param encoding 输出的文本编码
	 */
	public AuthServletResponseWrapper(HttpServletResponse response, String encoding) {
		super(response);
		this.charEncoding = encoding;
		// 一个网页的纯HTML大约为16KB，默认的只有32byte，这样写效率稍高，不用每次不够长时重建数组
		output = new ByteArrayOutputStream(1024*16);
		writer = new PrintWriter(new OutputStreamWriter(output, Charset.forName(charEncoding)));		
	}	
	
	/**
	 * 获取当前响应的文本输出
	 * @return
	 * @throws IOException 
	 */
	public String getOutputText() throws IOException{
		flushBuffer();
		return output.toString(charEncoding);
	}
	
	@Override
	public ServletOutputStream getOutputStream() throws IOException {
		return new ServletOutputStream() {			
			@Override
			public void write(int b) throws IOException {
				output.write(b);
			}
		};
	}
	
	@Override
	public PrintWriter getWriter() throws IOException {
		return writer;		
	}
	
	@Override
	public void flushBuffer() throws IOException {
		writer.flush();
		super.flushBuffer();
	}
	
	@Override
	public void reset() {
		output.reset();
		super.reset();
	}
	
	@Override
	public void sendError(int sc) throws IOException {
		httpStatus = sc;
		super.sendError(sc);
	}
	
	@Override
	public void sendError(int sc, String msg) throws IOException {
		httpStatus = sc;
		super.sendError(sc, msg);
	}
	
	/**
	 * 获取HTTP状态
	 * @return
	 */
	public int getHttpStatus(){
		// httpStatus在协议中虽然正常应是200，但由于ServletAPI所致这里0是正常，所以人工转换
		if(httpStatus == 0) httpStatus = 200;
		
		return httpStatus;
	}
	
}
